package com.tianji.learning.service.impl;

import com.tianji.api.client.user.UserClient;
import com.tianji.api.dto.user.UserDTO;
import com.tianji.common.utils.CollUtils;
import com.tianji.common.utils.DateUtils;
import com.tianji.common.utils.UserContext;
import com.tianji.learning.constants.RedisConstants;
import com.tianji.learning.domain.po.PointsBoard;
import com.tianji.learning.domain.po.PointsBoardSeason;
import com.tianji.learning.domain.query.PointsBoardQuery;
import com.tianji.learning.domain.vo.PointsBoardItemVO;
import com.tianji.learning.domain.vo.PointsBoardVO;
import com.tianji.learning.mapper.PointsBoardMapper;
import com.tianji.learning.service.IPointsBoardService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import org.springframework.data.redis.core.BoundZSetOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 学霸天梯榜 服务实现类
 * </p>
 *
 * @author 积分榜
 * @since 2023-04-17
 */
@Service
@RequiredArgsConstructor
public class PointsBoardServiceImpl extends ServiceImpl<PointsBoardMapper, PointsBoard> implements IPointsBoardService {

    private final RedisTemplate redisTemplate;

    private final UserClient userClient;

    @Override
    public PointsBoardVO PagePoints(PointsBoardQuery query) {
        //判断是否是查询当前赛季
        Long season = query.getSeason();
        boolean b = season == null || season == 0;
        //获取key和redis
        LocalDateTime now = LocalDateTime.now();
        String key = RedisConstants.POINTS_BOARD_KEY_PREFIX + now.format(DateUtils.SIGN_DATE_SUFFIX_FORMATTER);

        //查询我的积分排名
        PointsBoard board = b ?
                queryMyCurrentBoard(key):             //查询当前榜单
                queryMyHistoryBoard(query);           //查询历史榜单
        //查询我的榜单列表
        List<PointsBoard> list = b ?
                queryCurrentBoardList(key,query.getPageNo(),query.getPageSize()):
                queryHistoryBoardList(query);
        //封装结果
        PointsBoardVO vo = new PointsBoardVO();
        if (board != null){
            vo.setPoints(board.getPoints());
            vo.setRank(board.getRank());
        }
        if (CollUtils.isEmpty(list)){
            return vo;
        }

        Set<Long> uIds = list.stream().map(PointsBoard::getUserId).collect(Collectors.toSet());
        List<UserDTO> userDTOS = userClient.queryUserByIds(uIds);
        Map<Long,String> userMap = new HashMap<>(uIds.size());
        if (CollUtils.isEmpty(userDTOS)) {
            userMap = userDTOS.stream().collect(Collectors.toMap(UserDTO::getId, UserDTO::getName));
        }
        //处理榜单列表
        List<PointsBoardItemVO> itemVOS = new ArrayList<>(list.size());
        for (PointsBoard p : list){
            PointsBoardItemVO v = new PointsBoardItemVO();
            itemVOS.add(v);
            v.setPoints(p.getPoints());
            v.setRank(p.getRank());
            v.setName(userMap.get(p.getUserId()));
        }
        vo.setBoardList(itemVOS);
        return vo;
    }

    @Override
    public void createPointBboardTableByseacon(Integer seccer) {
        getBaseMapper().createPointBboardTableByseacon("points_board_" + seccer);
    }


    private List<PointsBoard> queryHistoryBoardList(PointsBoardQuery query) {
        return null;
    }

    //分页查询
    @Override
    public List<PointsBoard> queryCurrentBoardList(String key, Integer pageNo, Integer pageSize) {
        int form = (pageNo - 1) * pageSize;
        Set<ZSetOperations.TypedTuple<String>> set = redisTemplate.opsForZSet().reverseRangeWithScores(key, form, form * pageSize - 1);
        if (CollUtils.isEmpty(set)){
            return CollUtils.emptyList();
        }
        int rank = 1;
        List<PointsBoard> list =new ArrayList<>(set.size());
        for (ZSetOperations.TypedTuple<String> tuple : set){
            String userId = tuple.getValue();
            Double point = tuple.getScore();
            if (userId == null || point == null){
                continue;
            }
            PointsBoard d = new PointsBoard();
            d.setUserId(Long.valueOf(userId));
            d.setPoints(point.intValue());
            d.setRank(rank++);
            list.add(d);
        }
        return  list;
    }

    //查询历史榜单
    private PointsBoard queryMyHistoryBoard(PointsBoardQuery query) {
        return  null;
    }

    // 查询当前榜单
    private PointsBoard queryMyCurrentBoard(String key) {
        //绑定key
        BoundZSetOperations<String,String> ops = redisTemplate.boundZSetOps(key);
        //查询当前用户信息
        String user = UserContext.getUser().toString();
        //查询积分
        Double score = ops.score(user);
        //查询排行
        Long rank = ops.rank(score);
        //封装返回
        PointsBoard p = new PointsBoard();
        p.setPoints(score == null ? 0 : score.intValue());
        p.setRank(rank == null ? 0 : rank.intValue() + 1);
        return p;
    }


}
